//
// Created by gaodapeng on 2020/4/19.
//

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "strs.h"


/**
 * c语言的字符串，就是字符数组
 */
void str1() {

    char str[10] = {'h', 'e', 'l', 'l', 'o', '\0'};//特殊的字符数组
    char str1[10] = "hello";//\0默认省略
    char *str2 = "hello";

    printf("str=%s\n", str);
    printf("str1=%s\n", str1);
    printf("str2=%s\n", str2);

}


void str2() {
    printf("输入一个字符串\n");
    char str[10];
//    scanf("%s", str);//如果输入太多，就会溢出，崩溃
    fgets(str, 10, stdin);//安全的输入，多余的不会输入进去

    //这里会有一个情况，输出的时候只会有9个字符，因为字符串是由\0来结束的（不是字符0，是非号!），而0占一个位置
    printf("%s\n", str);
}

/**
 * 如何给字符数组赋值？
 */
void str3() {
    printf("给字符数组赋值\n");
    char str[10] = "abc";
    //1.循环
    for (int i = 0; i < 10; ++i) {
        str[i] = "abc"[i];
    }
    printf("str=%s\n", str);
    //2.函数库
    strcpy(str, "bbdf");
    printf("str=%s\n", str);
    printf("sizeof=%lu\n", sizeof(str));
    printf("sizeof=%lu\n", strlen(str));//strlen才可以获取字符串的长度，算到\0, \0本身没有算进去
    strcpy(str, "fff\0ffff");
    printf("str=%s\n", str);//如果中间有\0，那么只算到\0
    printf("sizeof=%lu\n", strlen(str));
    printf("sizeof=%lu\n", strlen(str));//strlen函数有个可能的问题，如果整个数组中没有\0，那么可能会多一个值,因为其循环的方式可能是++i

}

char *strconcat(char *s1, char *s2) {
    while (*s1)s1++;
    while ((*s1++ = *s2++));

}

/**
 * 数组合并
 *
 * strcat
 * strcpy
 * strncpy 范围拷贝
 * strcmp
 *
 */
void str4() {
    printf("字符串拼接\n");
    char s1[] = "abc";//不能用char*s1，为何？因为char*s1="abc"是存在常量区的，不可写，只读
    char s2[] = "1234";//而str[]是存在栈上的。可读可写
    strconcat(s1, s2);
    puts(s1);

//    printf("输入s3\n");
//    char s3[10];
//    fgets(s3, 10, stdin);
//    printf("s3=%s", s3);
//    printf("输入s4\n");
////    char *s4;//这种写法是不能执行下面的
//    char *s4 = (char *) calloc(10, sizeof(char));//这里是不能的
//    fgets(s4, 10, stdin);
//    printf("s4=%s", s4);
//    free(s4);
//    s4 = NULL;

//    char *s5 = "hello";//超限
    char *s5 = "he";
    strcpy(s1, s5);
    printf("s1=%s\n", s1);

    char s6[10] = "abc";
    strncpy(s6, "123456", 3);
    printf("s6=%s\n", s6);


    printf("%d\n", strcmp("abc2", "abc1"));//相等为0，前者大为1，后者大为-1

}

/**
 * 字符串数组
 * 用指针数组和二维数组的表示方式，其赋值和值copy的操作可行性是不同的。
 * 指针数组的指向可以改，但是值不可以改（值在常量区，指针在栈上）(常量指针)
 * 二维数组的指针不可改，但是值可以改（值在栈上）(指针常量)
 */
void str5() {
    char str[4][6] = {"abcd", "1234", "aaa", "bbbb"};
    char *str1[4] = {"abc", "adf", "123"};
//    str[0] = "aaaa";//str[0]是一个一维数组的数组名(常量，不可以作为左值)
    str[3][1] = '$';
    strcpy(str[0], "aaaa");
    printf("str[3]=%s\n", str[3]);
    printf("str[0]=%s\n", str[0]);
    str1[0] = "ABC";//这样是可以的，因为不像str[0]一样是常量，str1[0]是指针
//    strcpy(str1[0], "abc");//这样不行，因为指针指向常量区
}

